package com.utooo.service.purchase;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.utooo.constant.ResultCodeConstant;
import com.utooo.dao.purchase.OrderInventoryDetailMapper;
import com.utooo.dao.purchase.OrderInventoryMapper;
import com.utooo.dao.purchase.OrderReceiptDetailMapper;
import com.utooo.dao.purchase.OrderReceiptMapper;
import com.utooo.dao.purchase.OrderReconciliationDetailMapper;
import com.utooo.dao.purchase.OrderReconciliationMapper;
import com.utooo.dao.purchase.PurchaseOrderMapper;
import com.utooo.dao.quality.InspectionTaskMapper;
import com.utooo.dao.supplier.SupplierOrderReconciliationMapper;
import com.utooo.pojo.domain.purchase.order.OrderInventoryDO;
import com.utooo.pojo.domain.purchase.order.OrderInventoryDetailDO;
import com.utooo.pojo.domain.purchase.order.OrderReceiptDO;
import com.utooo.pojo.domain.purchase.order.OrderReceiptDetailDO;
import com.utooo.pojo.domain.purchase.order.OrderReconciliationDO;
import com.utooo.pojo.domain.purchase.order.OrderReconciliationDetailDO;
import com.utooo.pojo.domain.purchase.order.PurchaseOrderDO;
import com.utooo.pojo.domain.quality.InspectionTaskDO;
import com.utooo.pojo.domain.supplier.settlement.SupplierOrderReconciliationDO;
import com.utooo.pojo.dto.common.RestResult;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

import static com.utooo.constant.Constans.IGNORED_PROPERTIES;

@Service
@Slf4j
public class OrderInventoryServiceImpl extends ServiceImpl<OrderInventoryMapper, OrderInventoryDO>
        implements OrderInventoryService {

    @Resource
    private OrderReceiptMapper orderReceiptMapper;
    @Resource
    private OrderReceiptDetailMapper orderReceiptDetailMapper;
    @Resource
    private OrderInventoryDetailMapper orderInventoryDetailMapper;
    @Resource
    private InspectionTaskMapper inspectionTaskMapper;
    @Resource
    private OrderReconciliationMapper orderReconciliationMapper;
    @Resource
    private OrderReconciliationDetailMapper orderReconciliationDetailMapper;
    @Resource
    private PurchaseOrderMapper purchaseOrderMapper;
    @Resource
    private OrderReconciliationService orderReconciliationService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResult<String> addOrderInventory(String inspectionTaskId) {
        InspectionTaskDO inspectionTask = inspectionTaskMapper.selectById(inspectionTaskId);
        if (inspectionTask == null) {
            log.error("进货查验任务为空！, inspectionTaskId: {}", inspectionTaskId);
            return new RestResult<>(ResultCodeConstant.CODE_400, "进货查验任务为空！");
        }
        List<OrderInventoryDO> orderInventoryList = this.list(new LambdaQueryWrapper<OrderInventoryDO>()
                .eq(OrderInventoryDO::getInspectionTaskId, inspectionTaskId));
        if (CollUtil.isNotEmpty(orderInventoryList)) {
            log.error("该进货查验任务已入库！, inspectionTaskId: {}", inspectionTaskId);
            return new RestResult<>(ResultCodeConstant.CODE_400, "该记录已操作，请勿重复操作！");
        }

        String receiptNo = inspectionTask.getReceiptNo();
        OrderReceiptDO orderReceipt = orderReceiptMapper.selectOne(
                new LambdaQueryWrapper<OrderReceiptDO>().eq(OrderReceiptDO::getId, receiptNo));
        if (orderReceipt == null) {
            log.error("OrderReceipt not found, orderReceiptNo: {}", inspectionTaskId);
            return new RestResult<>(ResultCodeConstant.CODE_400, "收货不存在！");
        }
        String receiptDetailId = inspectionTask.getReceiptDetailId();
        OrderReceiptDetailDO orderReceiptDetail = orderReceiptDetailMapper
                .selectOne(new LambdaQueryWrapper<OrderReceiptDetailDO>()
                        .eq(OrderReceiptDetailDO::getId, receiptDetailId));
        if (orderReceiptDetail == null) {
            log.error("收货明细为空, orderReceiptDetailId: {}", receiptDetailId);
            return new RestResult<>(ResultCodeConstant.CODE_400, "收货明细为空！");
        }

        PurchaseOrderDO purchaseOrder = purchaseOrderMapper.selectOne(new LambdaQueryWrapper<PurchaseOrderDO>()
                .eq(PurchaseOrderDO::getOrderNo, orderReceipt.getOrderNo()));
        if (purchaseOrder == null) {
            log.error("采购订单不存在, orderNo: {}", orderReceipt.getOrderNo());
            return new RestResult<>(ResultCodeConstant.CODE_400, "采购订单不存在！");
        }

        OrderInventoryDO orderInventoryDO = new OrderInventoryDO();
        orderInventoryDO.setInspectionTaskId(inspectionTaskId);
        // 已入库
        orderInventoryDO.setStatus("3");
        orderInventoryDO.setInventoryNo(generateInventoryNo());
        Integer storableQuantity = inspectionTask.getStorableQuantity();
        orderInventoryDO.setTotalQuantity(storableQuantity);
        orderInventoryDO.setInventoryDate(LocalDateTime.now());
        this.save(orderInventoryDO);

        OrderInventoryDetailDO orderInventoryDetail = new OrderInventoryDetailDO();
        BeanUtil.copyProperties(orderReceiptDetail, orderInventoryDetail, IGNORED_PROPERTIES);
        orderInventoryDetail.setReceiptNo(receiptNo);
        orderInventoryDetail.setInspectionHandlingMeasure(inspectionTask.getHandlingMeasure());
        orderInventoryDetail.setStorableQuantity(storableQuantity);
        orderInventoryDetail.setInspectionQualifiedQuantity(inspectionTask.getQualifiedQuantity());
        orderInventoryDetail.setReceivedQuantity(inspectionTask.getSubmittedQuantity());
        orderInventoryDetail.setForeignId(orderInventoryDO.getId());
        orderInventoryDetailMapper.insert(orderInventoryDetail);

        // 生成订单业务对账单
        OrderReconciliationDO orderReconciliation = new OrderReconciliationDO();
        BeanUtil.copyProperties(orderReceipt, orderReconciliation, IGNORED_PROPERTIES);
        orderReconciliation.setReconciliationNo(orderReconciliationService.generateReconciliationNo());
        orderReconciliation.setTotalReconciliationQuantity(orderReceipt.getReceivedTotalQuantity());
        orderReconciliation.setExpectedAmountIncludingTax(orderReceipt.getReceivedAmountIncludingTax());
        orderReconciliation.setPurchaser(purchaseOrder.getPurchaser());
        orderReconciliation.setReconciliationType("1");
        orderReconciliation.setStatus("1");
        orderReconciliationMapper.insert(orderReconciliation);

        OrderReconciliationDetailDO orderReconciliationDetail = new OrderReconciliationDetailDO();
        BeanUtil.copyProperties(orderReceiptDetail, orderReconciliationDetail, IGNORED_PROPERTIES);
        orderReconciliationDetail.setSourceDocumentNo(orderReceipt.getReceiptNo());
        orderReconciliationDetail.setForeignId(orderReconciliation.getId());
        orderReconciliationDetailMapper.insert(orderReconciliationDetail);
        return new RestResult<>(ResultCodeConstant.CODE_200, ResultCodeConstant.CODE_200_MSG);
    }

    private String generateInventoryNo() {
        String prefix = "PK";
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        String datePart = currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 查询当天已有的最大订单号
        LambdaQueryWrapper<OrderInventoryDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.likeRight(OrderInventoryDO::getInventoryNo, prefix + datePart);
        queryWrapper.orderByDesc(OrderInventoryDO::getInventoryNo);
        queryWrapper.last("LIMIT 1");
        OrderInventoryDO orderInventoryDO = this.getOne(queryWrapper);

        // 生成序列号
        int maxSequence = 0;
        if (orderInventoryDO != null) {
            String inventoryNo = orderInventoryDO.getInventoryNo();
            maxSequence = Integer.parseInt(inventoryNo.substring((prefix + datePart).length()));
        }
        int nextSequence = maxSequence + 1;
        String sequencePart = String.format("%03d", nextSequence);
        return prefix + datePart + sequencePart;
    }
}